package com.example.demo.service;

import com.example.demo.base.ExecResult;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Component
public class ExecService {

    /**
     * 执行命令
     * @param commands
     * @return
     */
    public ExecResult execCommand(List<String> commands) {
        System.out.println("ExecCommand: " + commands);

        OutputStream os = null;
        InputStream is = null;

        ExecResult execResult = new ExecResult();
        ProcessBuilder processBuilder = new ProcessBuilder(commands);
        processBuilder.redirectErrorStream(true);
        Process process = null;
        try {
            process = processBuilder.start();
            execResult.setExitCode(process.waitFor());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        os = process.getOutputStream();
        is = process.getInputStream();
        try {
            os.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        List<String> result = br.lines().filter(l -> l != null).collect(Collectors.toList());
        System.out.println("ExecCommand result:" + result);
        execResult.setResult(result);
        return execResult;
    }

    /**
     * 使用正则表达式对参数格式化处理
     * 比如：systemctl start keepalived如果不通过正则会被以空格分割拆分3个命令执行显然有误
     *       /home/jar/test.sh start如果不通过正则会被以空格分割拆分2个命令执行显然有误
     * @param param
     * @return
     */
    public List<String> parseCommand(String param) {
        List<String> result = new ArrayList<String>();
        Pattern pattern = Pattern.compile("((?<=('))[\\w|[\\W&&[^']] ]*(?=((')(\\s|$))))|((?<!')[\\w|[/\\.\\-\\:>\\\\]]+(?!'))");
        Matcher matcher = pattern.matcher(param);
        while (matcher.find()) {
            result.add(matcher.group());
        }
        return result;
    }

}
